home *** CD-ROM | disk | FTP | other *** search
/ SunSoft Catalyst CDWARE 1996 May to August / Catalyst CDWARE 1996 May to August.iso / .products / .bin / httpd / Solaris_1 / pod2man < prev    next >
Text File  |  1995-06-14  |  14KB  |  628 lines

  1. #!~satyen/bin/perl5/perl
  2. eval 'exec ~satyen/bin/perl5/perl -S $0 ${1+"$@"}'
  3.     if $running_under_some_shell;
  4.  
  5. $/ = "";
  6. $cutting = 1;
  7.  
  8. $CFont = 'CW';
  9. if ($ARGV[0] =~ s/-fc(.*)//) {
  10.     shift;
  11.     $CFont = $1 || shift;
  12. }
  13.  
  14. if (length($CFont) == 2) {
  15.     $CFont_embed = "\\f($CFont";
  16. elsif (length($CFont) == 1) {
  17.     $CFont_embed = "\\f$CFont";
  18. else {
  19.     die "Roff font should be 1 or 2 chars, not `$CFont_embed'";
  20.  
  21. $name = @ARGV ? $ARGV[0] : "something";
  22. $name =~ s/\..*//;
  23.  
  24. print <<"END";
  25. .rn '' }`
  26. ''' \$RCSfile\$\$Revision\$\$Date\$
  27. ''' 
  28. ''' \$Log\$
  29. ''' 
  30. .de Sh
  31. .br
  32. .if t .Sp
  33. .ne 5
  34. .PP
  35. \\fB\\\\\$1\\fR
  36. .PP
  37. ..
  38. .de Sp
  39. .if t .sp .5v
  40. .if n .sp
  41. ..
  42. .de Ip
  43. .br
  44. .ie \\\\n(.\$>=3 .ne \\\\\$3
  45. .el .ne 3
  46. .IP "\\\\\$1" \\\\\$2
  47. ..
  48. .de Vb
  49. .ft $CFont
  50. .nf
  51. .ne \\\\\$1
  52. ..
  53. .de Ve
  54. .ft R
  55.  
  56. .fi
  57. ..
  58. '''
  59. '''
  60. '''     Set up \\*(-- to give an unbreakable dash;
  61. '''     string Tr holds user defined translation string.
  62. '''     Bell System Logo is used as a dummy character.
  63. '''
  64. .tr \\(*W-|\\(bv\\*(Tr
  65. .ie n \\{\\
  66. .ds -- \\(*W-
  67. .if (\\n(.H=4u)&(1m=24u) .ds -- \\(*W\\h'-12u'\\(*W\\h'-12u'-\\" diablo 10 pitch
  68. .if (\\n(.H=4u)&(1m=20u) .ds -- \\(*W\\h'-12u'\\(*W\\h'-8u'-\\" diablo 12 pitch
  69. .ds L" ""
  70. .ds R" ""
  71. .ds L' '
  72. .ds R' '
  73. 'br\\}
  74. .el\\{\\
  75. .ds -- \\(em\\|
  76. .tr \\*(Tr
  77. .ds L" ``
  78. .ds R" ''
  79. .ds L' `
  80. .ds R' '
  81. .if t .ds PI \\(*p
  82. .if n .ds PI PI
  83. 'br\\}
  84. .TH \U$name\E 1 "\\*(RP"
  85. .UC
  86. END
  87.  
  88. print <<'END';
  89. .if n .hy 0 
  90. .if n .na
  91. .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
  92. .de CQ          \" put $1 in typewriter font
  93. END
  94. print ".ft $CFont\n";
  95. print <<'END';
  96. 'if n "\c
  97. 'if t \\&\\$1\c
  98. 'if n \\&\\$1\c
  99. 'if n \&"
  100. \\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7
  101. '.ft R
  102. ..
  103. .\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2
  104. .    \" AM - accent mark definitions
  105. .bd S B 3
  106. .    \" fudge factors for nroff and troff
  107. .if n \{\
  108. .    ds #H 0
  109. .    ds #V .8m
  110. .    ds #F .3m
  111. .    ds #[ \f1
  112. .    ds #] \fP
  113. .\}
  114. .if t \{\
  115. .    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
  116. .    ds #V .6m
  117. .    ds #F 0
  118. .    ds #[ \&
  119. .    ds #] \&
  120. .\}
  121. .    \" simple accents for nroff and troff
  122. .if n \{\
  123. .    ds ' \&
  124. .    ds ` \&
  125. .    ds ^ \&
  126. .    ds , \&
  127. .    ds ~ ~
  128. .    ds ? ?
  129. .    ds ! !
  130. .    ds / 
  131. .    ds q 
  132. .\}
  133. .if t \{\
  134. .    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
  135. .    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
  136. .    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
  137. .    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
  138. .    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
  139. .    ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10'
  140. .    ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m'
  141. .    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
  142. .    ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10'
  143. .\}
  144. .    \" troff and (daisy-wheel) nroff accents
  145. .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
  146. .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
  147. .ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#]
  148. .ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u'
  149. .ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u'
  150. .ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#]
  151. .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
  152. .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
  153. .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
  154. .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
  155. .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
  156. .ds ae a\h'-(\w'a'u*4/10)'e
  157. .ds Ae A\h'-(\w'A'u*4/10)'E
  158. .ds oe o\h'-(\w'o'u*4/10)'e
  159. .ds Oe O\h'-(\w'O'u*4/10)'E
  160. .    \" corrections for vroff
  161. .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
  162. .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
  163. .    \" for low resolution devices (crt and lpr)
  164. .if \n(.H>23 .if \n(.V>19 \
  165. \{\
  166. .    ds : e
  167. .    ds 8 ss
  168. .    ds v \h'-1'\o'\(aa\(ga'
  169. .    ds _ \h'-1'^
  170. .    ds . \h'-1'.
  171. .    ds 3 3
  172. .    ds o a
  173. .    ds d- d\h'-1'\(ga
  174. .    ds D- D\h'-1'\(hy
  175. .    ds th \o'bp'
  176. .    ds Th \o'LP'
  177. .    ds ae ae
  178. .    ds Ae AE
  179. .    ds oe oe
  180. .    ds Oe OE
  181. .\}
  182. .rm #[ #] #H #V #F C
  183. END
  184.  
  185. $indent = 0;
  186.  
  187. while (<>) {
  188.     if ($cutting) {
  189.     next unless /^=/;
  190.     $cutting = 0;
  191.     }
  192.     chomp;
  193.  
  194.     # Translate verbatim paragraph
  195.  
  196.     if (/^\s/) {
  197.     @lines = split(/\n/);
  198.     for (@lines) {
  199.         1 while s
  200.         {^( [^\t]* ) \t ( \t* ) }
  201.         { $1 . ' ' x (8 - (length($1)%8) + 8 * (length($2))) }ex;
  202.         s/\\/\\e/g;
  203.         s/\A/\\&/s;
  204.     }
  205.     $lines = @lines;
  206.     makespace() unless $verbatim++;
  207.     print ".Vb $lines\n";
  208.     print join("\n", @lines), "\n";
  209.     print ".Ve\n";
  210.     $needspace = 0;
  211.     next;
  212.     }
  213.  
  214.     $verbatim = 0;
  215.  
  216.     # check for things that'll hosed our noremap scheme; affects $_
  217.     init_noremap();
  218.  
  219.     if (!/^=item/) {
  220.  
  221.     # trofficate backslashes; must do it before what happens below
  222.     s/\\/noremap('\\e')/ge;
  223.  
  224.     # first hide the escapes in case we need to 
  225.     # intuit something and get it wrong due to fmting
  226.  
  227.     s/([A-Z]<[^<>]*>)/noremap($1)/ge;
  228.  
  229.     # func() is a reference to a perl function
  230.     s{
  231.         \b
  232.         (
  233.         [:\w]+ \(\)
  234.         )
  235.     } {I<$1>}gx;
  236.  
  237.     # func(n) is a reference to a man page
  238.     s{
  239.         (\w+)
  240.         (
  241.         \(
  242.             [^\s,\051]+
  243.         \)
  244.         )
  245.     } {I<$1>\\|$2}gx;
  246.  
  247.     # convert simple variable references
  248.     s/(\s+)([\$\@%][\w:]+)/${1}C<$2>/g;
  249.  
  250.     if (m{ (
  251.             [\-\w]+
  252.             \(
  253.             [^\051]*?
  254.             [\@\$,]
  255.             [^\051]*?
  256.             \)
  257.         )
  258.         }x && $` !~ /([LCI]<[^<>]*|-)$/ && !/^=\w/) 
  259.     {
  260.         warn "``$1'' should be a [LCI]<$1> ref";
  261.     } 
  262.  
  263.     while (/(-[a-zA-Z])\b/g && $` !~ /[\w\-]$/) {
  264.         warn "``$1'' should be [CB]<$1> ref";
  265.     } 
  266.  
  267.     # put it back so we get the <> processed again;
  268.     clear_noremap(0); # 0 means leave the E's
  269.  
  270.     } else {
  271.     # trofficate backslashes
  272.     s/\\/noremap('\\e')/ge;
  273.  
  274.     } 
  275.  
  276.     # need to hide E<> first; they're processed in clear_noremap
  277.     s/(E<[^<>]+>)/noremap($1)/ge;
  278.  
  279.  
  280.     $maxnest = 10;
  281.     while ($maxnest-- && /[A-Z]</) {
  282.  
  283.     # can't do C font here
  284.     s/([BI])<([^<>]*)>/font($1) . $2 . font('R')/eg;
  285.  
  286.     # files and filelike refs in italics
  287.     s/F<([^<>]*)>/I<$1>/g;
  288.  
  289.     # no break -- usually we want C<> for this
  290.     s/S<([^<>]*)>/nobreak($1)/eg;
  291.  
  292.     # LREF: a manpage(3f) 
  293.     s:L<([a-zA-Z][^\s\/]+)(\([^\)]+\))?>:the I<$1>$2 manpage:g;
  294.  
  295.     # LREF: an =item on another manpage
  296.     s{
  297.         L<
  298.         ([^/]+)
  299.         /
  300.         (
  301.             [:\w]+
  302.             (\(\))?
  303.         )
  304.         >
  305.     } {the C<$2> entry in the I<$1> manpage}gx;
  306.  
  307.     # LREF: an =item on this manpage
  308.     s{
  309.        ((?:
  310.         L<
  311.         /
  312.         (
  313.             [:\w]+
  314.             (\(\))?
  315.         )
  316.         >
  317.         (,?\s+(and\s+)?)?
  318.       )+)
  319.     } { internal_lrefs($1) }gex;
  320.  
  321.     # LREF: a =head2 (head1?), maybe on a manpage, maybe right here
  322.     # the "func" can disambiguate
  323.     s{
  324.         L<
  325.         (?:
  326.             ([a-zA-Z]\S+?) / 
  327.         )?
  328.         "?(.*?)"?
  329.         >
  330.     }{
  331.         do {
  332.         $1     # if no $1, assume it means on this page.
  333.             ?  "the section on I<$2> in the I<$1> manpage"
  334.             :  "the section on I<$2>"
  335.         } 
  336.     }gex;
  337.  
  338.     s/Z<>/\\&/g;
  339.  
  340.     # comes last because not subject to reprocessing
  341.     s/C<([^<>]*)>/noremap("${CFont_embed}${1}\\fR")/eg;
  342.     }
  343.  
  344.     if (s/^=//) {
  345.     $needspace = 0;        # Assume this.
  346.  
  347.     s/\n/ /g;
  348.  
  349.     ($Cmd, $_) = split(' ', $_, 2);
  350.  
  351.     if (defined $_) {
  352.         &escapes;
  353.         s/"/""/g;
  354.     }
  355.  
  356.     clear_noremap(1);
  357.  
  358.     if ($Cmd eq 'cut') {
  359.         $cutting = 1;
  360.     }
  361.     elsif ($Cmd eq 'head1') {
  362.         print qq{.SH "$_"\n}
  363.     }
  364.     elsif ($Cmd eq 'head2') {
  365.         print qq{.Sh "$_"\n}
  366.     }
  367.     elsif ($Cmd eq 'over') {
  368.         push(@indent,$indent);
  369.         $indent = $_ + 0;
  370.     }
  371.     elsif ($Cmd eq 'back') {
  372.         $indent = pop(@indent);
  373.         warn "Unmatched =back\n" unless defined $indent;
  374.         $needspace = 1;
  375.     }
  376.     elsif ($Cmd eq 'item') {
  377.         s/^\*( |$)/\\(bu$1/g;
  378.         print STDOUT qq{.Ip "$_" $indent\n};
  379.     }
  380.     else {
  381.         warn "Unrecognized directive: $Cmd\n";
  382.     }
  383.     }
  384.     else {
  385.     if ($needspace) {
  386.         &makespace;
  387.     }
  388.     &escapes;
  389.     clear_noremap(1);
  390.     print $_, "\n";
  391.     $needspace = 1;
  392.     }
  393. }
  394.  
  395. print <<"END";
  396.  
  397. .rn }` ''
  398. END
  399.  
  400. #########################################################################
  401.  
  402. sub nobreak {
  403.     my $string = shift;
  404.     $string =~ s/ /\\ /g;
  405.     $string;
  406. }
  407.  
  408. sub escapes {
  409.  
  410.     # translate the minus in foo-bar into foo\-bar for roff
  411.     s/([^0-9a-z-])-([^-])/$1\\-$2/g;
  412.  
  413.     # make -- into the string version \*(-- (defined above)
  414.     s/\b--\b/\\*(--/g;
  415.     s/"--([^"])/"\\*(--$1/g;  # should be a better way
  416.     s/([^"])--"/$1\\*(--"/g;
  417.  
  418.     # fix up quotes; this is somewhat tricky
  419.     if (!/""/) {
  420.     s/(^|\s)(['"])/noremap("$1\\*(L$2")/ge;
  421.     s/(['"])($|[\-\s,;\\!?.])/noremap("\\*(R$1$2")/ge;
  422.     }
  423.  
  424.     #s/(?!")(?:.)--(?!")(?:.)/\\*(--/g;
  425.     #s/(?:(?!")(?:.)--(?:"))|(?:(?:")--(?!")(?:.))/\\*(--/g;
  426.     
  427.  
  428.     # make sure that func() keeps a bit a space tween the parens
  429.     ### s/\b\(\)/\\|()/g;
  430.     ### s/\b\(\)/(\\|)/g;
  431.  
  432.     # make C++ into \*C+, which is a squinched version (defined above)
  433.     s/\bC\+\+/\\*(C+/g;
  434.  
  435.     # make double underbars have a little tiny space between them
  436.     s/__/_\\|_/g;
  437.  
  438.     # PI goes to \*(-- (defined above)
  439.     s/\bPI\b/noremap('\\*(PI')/ge;
  440.  
  441.     # make all caps a teeny bit smaller, but don't muck with embedded code literals
  442.     my $hidCFont = font('C');
  443.     if ($Cmd !~ /^head1/) { # SH already makes smaller
  444.     # /g isn't enough; 1 while or we'll be off
  445.  
  446. #    1 while s{
  447. #        (?!$hidCFont)(..|^.|^)
  448. #        \b
  449. #        (
  450. #        [A-Z][\/A-Z+:\-\d_$.]+
  451. #        )
  452. #        (s?)         
  453. #        \b
  454. #    } {$1\\s-1$2\\s0}gmox;
  455.  
  456.     1 while s{
  457.         (?!$hidCFont)(..|^.|^)
  458.         (
  459.         \b[A-Z]{2,}[\/A-Z+:\-\d_\$]*\b
  460.         )
  461.     } { 
  462.         $1 . noremap( '\\s-1' .  $2 . '\\s0' )
  463.     }egmox;
  464.  
  465.     }
  466. }
  467.  
  468. # make troff just be normal, but make small nroff get quoted
  469. # decided to just put the quotes in the text; sigh;
  470. sub ccvt {
  471.      local($_,$prev) = @_;
  472.      if ( /^\W+$/ && !/^\$./ ) {
  473.      ($prev && "\n") . noremap(qq{.CQ $_ \n\\&});
  474.      # what about $" ?
  475.      } else {
  476.      noremap(qq{${CFont_embed}$_\\fR});
  477.      } 
  478.     noremap(qq{.CQ "$_" \n\\&});
  479.  
  480. sub makespace {
  481.     if ($indent) {
  482.     print ".Sp\n";
  483.     }
  484.     else {
  485.     print ".PP\n";
  486.     }
  487. }
  488.  
  489. sub font {
  490.     local($font) = shift;
  491.     return '\\f' . noremap($font);
  492.  
  493. sub noremap {
  494.     local($thing_to_hide) = shift;
  495.     $thing_to_hide =~ tr/\000-\177/\200-\377/;
  496.     return $thing_to_hide;
  497.  
  498. sub init_noremap {
  499.     if ( /[\200-\377]/ ) {
  500.     warn "hit bit char in input stream";
  501.     } 
  502.  
  503. sub clear_noremap {
  504.     my $ready_to_print = $_[0];
  505.  
  506.     tr/\200-\377/\000-\177/;
  507.  
  508.     # trofficate backslashes
  509.     # s/(?!\\e)(?:..|^.|^)\\/\\e/g;
  510.  
  511.     # now for the E<>s, which have been hidden until now
  512.     # otherwise the interative \w<> processing would have
  513.     # been hosed by the E<gt>
  514.     s {
  515.         E<    
  516.         ( [A-Za-z]+ )    
  517.         >    
  518.     } { 
  519.      do {    
  520.          exists $HTML_Escapes{$1}
  521.         ? do { $HTML_Escapes{$1} }
  522.         : do {
  523.             warn "Unknown escape: $& in $_";
  524.             "E<$1>";
  525.         } 
  526.      } 
  527.     }egx if $ready_to_print;
  528.  
  529. sub internal_lrefs {
  530.     local($_) = shift;
  531.  
  532.     s{L</([^>]+)>}{$1}g;
  533.     my(@items) = split( /(?:,?\s+(?:and\s+)?)/ );
  534.     my $retstr = "the ";
  535.     my $i;
  536.     for ($i = 0; $i <= $#items; $i++) {
  537.     $retstr .= "C<$items[$i]>";
  538.     $retstr .= ", " if @items > 2 && $i != $#items;
  539.     $retstr .= " and " if $i+2 == @items;
  540.     } 
  541.  
  542.     $retstr .= " entr" . ( @items > 1  ? "ies" : "y" )
  543.         .  " elsewhere in this document";
  544.  
  545.     return $retstr;
  546.  
  547.  
  548. BEGIN {
  549. %HTML_Escapes = (
  550.     'amp'    =>    '&',    #   ampersand
  551.     'lt'    =>    '<',    #   left chevron, less-than
  552.     'gt'    =>    '>',    #   right chevron, greater-than
  553.     'quot'    =>    '"',    #   double quote
  554.  
  555.     "Aacute"    =>    "A\\*'",    #   capital A, acute accent
  556.     "aacute"    =>    "a\\*'",    #   small a, acute accent
  557.     "Acirc"    =>    "A\\*^",    #   capital A, circumflex accent
  558.     "acirc"    =>    "a\\*^",    #   small a, circumflex accent
  559.     "AElig"    =>    '\*(AE',    #   capital AE diphthong (ligature)
  560.     "aelig"    =>    '\*(ae',    #   small ae diphthong (ligature)
  561.     "Agrave"    =>    "A\\*`",    #   capital A, grave accent
  562.     "agrave"    =>    "A\\*`",    #   small a, grave accent
  563.     "Aring"    =>    'A\\*o',    #   capital A, ring
  564.     "aring"    =>    'a\\*o',    #   small a, ring
  565.     "Atilde"    =>    'A\\*~',    #   capital A, tilde
  566.     "atilde"    =>    'a\\*~',    #   small a, tilde
  567.     "Auml"    =>    'A\\*:',    #   capital A, dieresis or umlaut mark
  568.     "auml"    =>    'a\\*:',    #   small a, dieresis or umlaut mark
  569.     "Ccedil"    =>    'C\\*,',    #   capital C, cedilla
  570.     "ccedil"    =>    'c\\*,',    #   small c, cedilla
  571.     "Eacute"    =>    "E\\*'",    #   capital E, acute accent
  572.     "eacute"    =>    "e\\*'",    #   small e, acute accent
  573.     "Ecirc"    =>    "E\\*^",    #   capital E, circumflex accent
  574.     "ecirc"    =>    "e\\*^",    #   small e, circumflex accent
  575.     "Egrave"    =>    "E\\*`",    #   capital E, grave accent
  576.     "egrave"    =>    "e\\*`",    #   small e, grave accent
  577.     "ETH"    =>    '\\*(D-',    #   capital Eth, Icelandic
  578.     "eth"    =>    '\\*(d-',    #   small eth, Icelandic
  579.     "Euml"    =>    "E\\*:",    #   capital E, dieresis or umlaut mark
  580.     "euml"    =>    "e\\*:",    #   small e, dieresis or umlaut mark
  581.     "Iacute"    =>    "I\\*'",    #   capital I, acute accent
  582.     "iacute"    =>    "i\\*'",    #   small i, acute accent
  583.     "Icirc"    =>    "I\\*^",    #   capital I, circumflex accent
  584.     "icirc"    =>    "i\\*^",    #   small i, circumflex accent
  585.     "Igrave"    =>    "I\\*`",    #   capital I, grave accent
  586.     "igrave"    =>    "i\\*`",    #   small i, grave accent
  587.     "Iuml"    =>    "I\\*:",    #   capital I, dieresis or umlaut mark
  588.     "iuml"    =>    "i\\*:",    #   small i, dieresis or umlaut mark
  589.     "Ntilde"    =>    'N\*~',        #   capital N, tilde
  590.     "ntilde"    =>    'n\*~',        #   small n, tilde
  591.     "Oacute"    =>    "O\\*'",    #   capital O, acute accent
  592.     "oacute"    =>    "o\\*'",    #   small o, acute accent
  593.     "Ocirc"    =>    "O\\*^",    #   capital O, circumflex accent
  594.     "ocirc"    =>    "o\\*^",    #   small o, circumflex accent
  595.     "Ograve"    =>    "O\\*`",    #   capital O, grave accent
  596.     "ograve"    =>    "o\\*`",    #   small o, grave accent
  597.     "Oslash"    =>    "O\\*/",    #   capital O, slash
  598.     "oslash"    =>    "o\\*/",    #   small o, slash
  599.     "Otilde"    =>    "O\\*~",    #   capital O, tilde
  600.     "otilde"    =>    "o\\*~",    #   small o, tilde
  601.     "Ouml"    =>    "O\\*:",    #   capital O, dieresis or umlaut mark
  602.     "ouml"    =>    "o\\*:",    #   small o, dieresis or umlaut mark
  603.     "szlig"    =>    '\*8',        #   small sharp s, German (sz ligature)
  604.     "THORN"    =>    '\\*(Th',    #   capital THORN, Icelandic
  605.     "thorn"    =>    '\\*(th',,    #   small thorn, Icelandic
  606.     "Uacute"    =>    "U\\*'",    #   capital U, acute accent
  607.     "uacute"    =>    "u\\*'",    #   small u, acute accent
  608.     "Ucirc"    =>    "U\\*^",    #   capital U, circumflex accent
  609.     "ucirc"    =>    "u\\*^",    #   small u, circumflex accent
  610.     "Ugrave"    =>    "U\\*`",    #   capital U, grave accent
  611.     "ugrave"    =>    "u\\*`",    #   small u, grave accent
  612.     "Uuml"    =>    "U\\*:",    #   capital U, dieresis or umlaut mark
  613.     "uuml"    =>    "u\\*:",    #   small u, dieresis or umlaut mark
  614.     "Yacute"    =>    "Y\\*'",    #   capital Y, acute accent
  615.     "yacute"    =>    "y\\*'",    #   small y, acute accent
  616.     "yuml"    =>    "y\\*:",    #   small y, dieresis or umlaut mark
  617. );
  618. }
  619.